<template>
  <button :class="[$style.button, { [$style.limited]: isLimited }]"
    @click="showRateLimitState = !showRateLimitState" v-bind="$attrs">Rate limiting</button>
  <div v-if="showRateLimitState"
    class="font-sans p-4 bg-gray-800 text-gray-400 mb-8 border border-gray-900 absolute bottom-0"
    style="border-width: 0.25rem;" v-bind="$attrs">
    <div v-for="limit in limits" :key="limit.policy">
      <div :class="{ 'text-red-400': limit.hasQueue }">Policy: {{ limit.policy }}</div>
      <div>
        <div v-for="(rule, idx) in limit.rules" :key="idx">
          <span>{{ rule.active }} / {{ rule.max }} over {{ rule.window }}s</span>
          <span v-if="rule.queue" class="pl-1">(queue: {{ rule.queue }})</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent } from 'vue'
import { RATE_LIMIT_RULES } from './common'
import { PriceCheckWidget } from '@/web/overlay/interfaces'
import { AppConfig } from '@/web/Config'

export default defineComponent({
  inheritAttrs: false,
  setup () {
    const widget = computed(() => AppConfig<PriceCheckWidget>('price-check')!)

    const limits = computed(() => {
      const LIMITS = [
        { policy: 'trade-search-request-limit', rules: RATE_LIMIT_RULES.SEARCH },
        { policy: 'trade-exchange-request-limit', rules: RATE_LIMIT_RULES.EXCHANGE },
        { policy: 'trade-fetch-request-limit', rules: RATE_LIMIT_RULES.FETCH }
      ]

      return LIMITS.map((limit) => ({
        policy: limit.policy,
        hasQueue: Array.from(limit.rules).some(rl => rl.queue.value),
        rules: Array.from(limit.rules).map(rl => ({
          max: rl.max,
          window: rl.window,
          active: rl.stack.length,
          queue: rl.queue.value
        }))
      }))
    })

    const isLimited = computed(() => limits.value.some(limit => limit.hasQueue))

    const showRateLimitState = computed<boolean>({
      get () {
        return widget.value.showRateLimitState
      },
      set (value) {
        widget.value.showRateLimitState = value
      }
    })

    return {
      limits,
      showRateLimitState,
      isLimited
    }
  }
})
</script>

<style lang="postcss" module>
.button {
  @apply mx-6 px-4;
  @apply bg-gray-900 text-gray-600;
  @apply rounded-t;
  @apply leading-6;
  position: absolute;
  bottom: 0;
}

.limited {
  @apply bg-red-700 text-red-200;

  /* Animate.css */
  :global {
    animation: shakeX;
    animation-duration: 1s;
  }
}
</style>
